#pragma once
#include "stdafx.h"
#include "ref_counter.h"
namespace async_curl {
	class curl_task;

	using tid_t = std::thread::id;

	class curl_event_loop {
		friend class curl_ctx;
	public:
		using task_list_t = std::list<curl_task*>;
		using refs_t = std::list<ref_counter>;
	public:
		curl_event_loop();
		~curl_event_loop();

		void add_task(curl_task* task);

		void start();
		void stop();

		bool inloop();

	private:
		//callback start
		static int curl_socket_fun(CURL *e, curl_socket_t s, int what, void *userp, void *sockp);
		static int curl_timer_fun(CURLM* m, long timeout_ms, void* userp);

		static void timer_cb(uv_timer_t*timer);

		static void async_addtask_cb(uv_async_t* async);
		static void async_shutdown_cb(uv_async_t* async);

		static void internal_cleanup_cb(uv_handle_t* h);

		void shutdown_signal_cb();
		//callback stop

		//not thread safe
		void check_curl_tasklist();
		//not thread safe
		void remove_all_curl_tasks();

		//not thread safe
		ref_counter get_refcounter() const;

	private:
		std::atomic_bool got_exit_;
		uv_loop_t * loop_;
		uv_timer_t *timer_;
		uv_async_t *async_;
		uv_async_t *shutdown_async_;
		CURLM * curlm_;
		task_list_t tasks_;
		std::recursive_mutex mtx_;
		refs_t internal_refs_;
		tid_t tid_;
	};
}
